home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Graphics Programming (2nd Edition) / Visual Basic Graphics Programming 2nd Edition.iso / OldSrc / CH10 / SRC / SURFACE2.FRM < prev    next >
Text File  |  1996-05-02  |  17KB  |  637 lines

  1. VERSION 4.00
  2. Begin VB.Form SurfaceForm 
  3.    Appearance      =   0  'Flat
  4.    BackColor       =   &H00C0C0C0&
  5.    Caption         =   "Surfaces"
  6.    ClientHeight    =   5700
  7.    ClientLeft      =   300
  8.    ClientTop       =   855
  9.    ClientWidth     =   9090
  10.    BeginProperty Font 
  11.       name            =   "MS Sans Serif"
  12.       charset         =   1
  13.       weight          =   700
  14.       size            =   8.25
  15.       underline       =   0   'False
  16.       italic          =   0   'False
  17.       strikethrough   =   0   'False
  18.    EndProperty
  19.    ForeColor       =   &H80000008&
  20.    Height          =   6390
  21.    KeyPreview      =   -1  'True
  22.    Left            =   240
  23.    LinkTopic       =   "Form1"
  24.    ScaleHeight     =   5700
  25.    ScaleWidth      =   9090
  26.    Top             =   225
  27.    Width           =   9210
  28.    Begin VB.CheckBox ShowAxesCheck 
  29.       Caption         =   "Show Axes"
  30.       Height          =   255
  31.       Left            =   7080
  32.       TabIndex        =   16
  33.       Top             =   3960
  34.       Width           =   2055
  35.    End
  36.    Begin VB.OptionButton Choice 
  37.       Caption         =   "Saddle"
  38.       Height          =   255
  39.       Index           =   8
  40.       Left            =   7080
  41.       TabIndex        =   15
  42.       Top             =   2880
  43.       Width           =   2055
  44.    End
  45.    Begin VB.OptionButton Choice 
  46.       Caption         =   "Cone"
  47.       Height          =   255
  48.       Index           =   7
  49.       Left            =   7080
  50.       TabIndex        =   14
  51.       Top             =   2520
  52.       Width           =   2055
  53.    End
  54.    Begin VB.OptionButton Choice 
  55.       Caption         =   "Holes"
  56.       Height          =   255
  57.       Index           =   6
  58.       Left            =   7080
  59.       TabIndex        =   13
  60.       Top             =   2160
  61.       Width           =   2055
  62.    End
  63.    Begin VB.TextBox PhiText 
  64.       Height          =   285
  65.       Left            =   3600
  66.       TabIndex        =   12
  67.       Text            =   "0.1570"
  68.       Top             =   5400
  69.       Width           =   855
  70.    End
  71.    Begin VB.TextBox ThetaText 
  72.       Height          =   285
  73.       Left            =   2040
  74.       TabIndex        =   10
  75.       Text            =   "0.6283"
  76.       Top             =   5400
  77.       Width           =   855
  78.    End
  79.    Begin VB.TextBox RText 
  80.       Height          =   285
  81.       Left            =   480
  82.       TabIndex        =   8
  83.       Text            =   "10"
  84.       Top             =   5400
  85.       Width           =   855
  86.    End
  87.    Begin VB.OptionButton Choice 
  88.       Caption         =   "Hemisphere"
  89.       Height          =   255
  90.       Index           =   5
  91.       Left            =   7080
  92.       TabIndex        =   7
  93.       Top             =   1800
  94.       Width           =   2055
  95.    End
  96.    Begin VB.OptionButton Choice 
  97.       Caption         =   "Randomized Ridges"
  98.       Height          =   255
  99.       Index           =   4
  100.       Left            =   7080
  101.       TabIndex        =   6
  102.       Top             =   1440
  103.       Width           =   2055
  104.    End
  105.    Begin VB.OptionButton Choice 
  106.       Caption         =   "Ridges"
  107.       Height          =   255
  108.       Index           =   3
  109.       Left            =   7080
  110.       TabIndex        =   5
  111.       Top             =   1080
  112.       Width           =   2055
  113.    End
  114.    Begin VB.OptionButton Choice 
  115.       Caption         =   "Bowl"
  116.       Height          =   255
  117.       Index           =   2
  118.       Left            =   7080
  119.       TabIndex        =   4
  120.       Top             =   720
  121.       Width           =   2055
  122.    End
  123.    Begin VB.OptionButton Choice 
  124.       Caption         =   "Mounds"
  125.       Height          =   255
  126.       Index           =   1
  127.       Left            =   7080
  128.       TabIndex        =   3
  129.       Top             =   360
  130.       Width           =   2055
  131.    End
  132.    Begin VB.OptionButton Choice 
  133.       Caption         =   "Splash"
  134.       Height          =   255
  135.       Index           =   0
  136.       Left            =   7080
  137.       TabIndex        =   2
  138.       Top             =   0
  139.       Value           =   -1  'True
  140.       Width           =   2055
  141.    End
  142.    Begin VB.PictureBox Pict 
  143.       AutoRedraw      =   -1  'True
  144.       Height          =   5295
  145.       Left            =   0
  146.       ScaleHeight     =   349
  147.       ScaleMode       =   3  'Pixel
  148.       ScaleWidth      =   461
  149.       TabIndex        =   0
  150.       Top             =   0
  151.       Width           =   6975
  152.    End
  153.    Begin MSComDlg.CommonDialog LoadDialog 
  154.       Left            =   7080
  155.       Top             =   4560
  156.       _version        =   65536
  157.       _extentx        =   847
  158.       _extenty        =   847
  159.       _stockprops     =   0
  160.       cancelerror     =   -1  'True
  161.    End
  162.    Begin VB.Label Label1 
  163.       Caption         =   "Phi"
  164.       Height          =   255
  165.       Index           =   2
  166.       Left            =   3240
  167.       TabIndex        =   11
  168.       Top             =   5400
  169.       Width           =   375
  170.    End
  171.    Begin VB.Label Label1 
  172.       Caption         =   "Theta"
  173.       Height          =   255
  174.       Index           =   1
  175.       Left            =   1440
  176.       TabIndex        =   9
  177.       Top             =   5400
  178.       Width           =   495
  179.    End
  180.    Begin VB.Label Label1 
  181.       Caption         =   "R"
  182.       Height          =   255
  183.       Index           =   0
  184.       Left            =   240
  185.       TabIndex        =   1
  186.       Top             =   5400
  187.       Width           =   255
  188.    End
  189.    Begin VB.Menu mnuFile 
  190.       Caption         =   "&File"
  191.       Begin VB.Menu mnuFileLoad 
  192.          Caption         =   "&Load..."
  193.          Shortcut        =   ^L
  194.       End
  195.       Begin VB.Menu mnuFileSaveAs 
  196.          Caption         =   "&Save As..."
  197.          Shortcut        =   ^A
  198.       End
  199.       Begin VB.Menu mnuFileSep 
  200.          Caption         =   "-"
  201.       End
  202.       Begin VB.Menu mnuFileExit 
  203.          Caption         =   "E&xit"
  204.       End
  205.    End
  206. End
  207. Attribute VB_Name = "SurfaceForm"
  208. Attribute VB_Creatable = False
  209. Attribute VB_Exposed = False
  210. Option Explicit
  211.  
  212. ' Location of viewing eye.
  213. Dim EyeR As Single
  214. Dim EyeTheta As Single
  215. Dim EyePhi As Single
  216.  
  217. Const Dtheta = PI / 20
  218. Const Dphi = PI / 20
  219. Const Dr = 1
  220.  
  221. ' Location of focus point.
  222. Const FocusX = 0#
  223. Const FocusY = 0#
  224. Const FocusZ = 0#
  225.  
  226. Dim Projector(1 To 4, 1 To 4) As Single
  227.  
  228. Dim ThePicture As ObjPicture
  229.  
  230. Dim ShowingParameters As Boolean
  231.  
  232. Dim ChoiceNum As Integer
  233.  
  234. ' ************************************************
  235. ' Return the surface's value at this point.
  236. ' ************************************************
  237. Function SurfaceValue(x As Single, z As Single) As Single
  238. Const Xmin = -5
  239. Const Amp = 0.25
  240. Const Per = 2 * PI / 4
  241. Const Amp2 = 1
  242. Const Per2 = 2 * PI / 16
  243. Const Amp3 = 2
  244. Const R2 = 16.81
  245.     
  246. Dim D As Single
  247. Dim x1 As Single
  248. Dim z1 As Single
  249. Dim x2 As Single
  250. Dim z2 As Single
  251. Dim y As Single
  252.  
  253.     Select Case ChoiceNum
  254.         Case 0  ' Splash.
  255.             D = Sqr(x * x + z * z)
  256.             y = Amp * Cos(3 * D)
  257.         
  258.         Case 1  ' Mounds.
  259.             y = Amp * (Cos(Per * x) + Cos(Per * z))
  260.         
  261.         Case 2  ' Bowl.
  262.             y = 0.2 * (x * x + z * z) - 5#
  263.         
  264.         Case 3  ' Ridges.
  265.             y = Amp2 * Cos(Per2 * x) + Amp3 * Cos(Per * z) / (Abs(z) / 3 + 1)
  266.     
  267.         Case 4  ' Random ridges.
  268.             y = Amp2 * Cos(Per2 * x) + Amp3 * Cos(Per * z) / (Abs(z) / 3 + 1) + Amp * Rnd / 2
  269.     
  270.         Case 5  ' Hemisphere.
  271.             D = x * x + z * z
  272.             If D >= R2 Then
  273.                 y = 0
  274.             Else
  275.                 y = Sqr(R2 - D)
  276.             End If
  277.         
  278.         Case 6  ' Holes.
  279.             x1 = (x + Xmin / 2)
  280.             z1 = (z + Xmin / 2)
  281.             x2 = (x - Xmin / 2)
  282.             z2 = (z - Xmin / 2)
  283.             y = Amp3 - _
  284.         1 / (x1 * x1 + z1 * z1 + 0.1) - _
  285.         1 / (x2 * x2 + z1 * z1 + 0.1) - _
  286.         1 / (x1 * x1 + z2 * z2 + 0.1) - _
  287.         1 / (x2 * x2 + z2 * z2 + 0.1)
  288.     
  289.         Case 7  ' Cone.
  290.             D = 2 * (Amp3 - Sqr(x * x + z * z))
  291.             If D < -Amp3 Then D = -Amp3
  292.             y = D
  293.     
  294.         Case 8  ' Saddle.
  295.             y = (x * x - z * z) / 10
  296.         
  297.     End Select
  298.     
  299.     SurfaceValue = y
  300. End Function
  301.  
  302.  
  303. ' *******************************************************
  304. ' Rotate the points in the cube and draw the cube.
  305. ' *******************************************************
  306. Private Sub DrawData(pic As Object)
  307. Dim x As Single
  308. Dim y As Single
  309. Dim z As Single
  310. Dim S(1 To 4, 1 To 4) As Single
  311. Dim t(1 To 4, 1 To 4) As Single
  312. Dim ST(1 To 4, 1 To 4) As Single
  313. Dim PST(1 To 4, 1 To 4) As Single
  314.  
  315.     MousePointer = vbHourglass
  316.     Refresh
  317.     
  318.     ' Prevent overflow errors when drawing lines
  319.     ' too far out of bounds.
  320.     On Error Resume Next
  321.     
  322.     ' Scale and translate so it looks OK in pixels.
  323.     m3Scale S, 35, -35, 1
  324.     m3Translate t, 230, 175, 0
  325.     m3MatMultiplyFull ST, S, t
  326.     m3MatMultiplyFull PST, Projector, ST
  327.     
  328.     ' Transform the points.
  329.     ThePicture.ApplyFull PST
  330.  
  331.     ' Display the data.
  332.     pic.Cls
  333.     ThePicture.Draw pic, EyeR
  334.     pic.Refresh
  335.  
  336.     ' Display the viewnig parameters.
  337.     ShowViewingParameters
  338.  
  339.     MousePointer = vbDefault
  340. End Sub
  341.  
  342. Sub ShowViewingParameters()
  343.     ShowingParameters = True
  344.     
  345.     RText.Text = Format$(EyeR, "0.0000")
  346.     ThetaText.Text = Format$(EyeTheta, "0.0000")
  347.     PhiText.Text = Format$(EyePhi, "0.0000")
  348.     
  349.     RText.Refresh
  350.     ThetaText.Refresh
  351.     PhiText.Refresh
  352.  
  353.     ShowingParameters = False
  354. End Sub
  355.  
  356. Private Sub Choice_Click(Index As Integer)
  357.     ChoiceNum = Index
  358.     CreateData (ShowAxesCheck.value = vbChecked)
  359.     DrawData Pict
  360.     Pict.SetFocus
  361. End Sub
  362.  
  363. Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
  364.     Select Case KeyCode
  365.         Case vbKeyLeft
  366.             EyeTheta = EyeTheta - Dtheta
  367.         
  368.         Case vbKeyRight
  369.             EyeTheta = EyeTheta + Dtheta
  370.         
  371.         Case vbKeyUp
  372.             EyePhi = EyePhi - Dphi
  373.         
  374.         Case vbKeyDown
  375.             EyePhi = EyePhi + Dphi
  376.                 
  377.         Case Else
  378.             Exit Sub
  379.     End Select
  380.  
  381.     m3PProject Projector, m3Perspective, EyeR, EyePhi, EyeTheta, FocusX, FocusY, FocusZ, 0, 1, 0
  382.     DrawData Pict
  383. End Sub
  384.  
  385.  
  386. Private Sub Form_KeyPress(KeyAscii As Integer)
  387.     Select Case KeyAscii
  388.         Case Asc("+")
  389.             EyeR = EyeR + Dr
  390.         
  391.         Case Asc("-")
  392.             EyeR = EyeR - Dr
  393.         
  394.         Case Else
  395.             Exit Sub
  396.     End Select
  397.  
  398.     m3PProject Projector, m3Perspective, EyeR, EyePhi, EyeTheta, FocusX, FocusY, FocusZ, 0, 1, 0
  399.     DrawData Pict
  400. End Sub
  401.  
  402. Private Sub Form_Load()
  403.     ' Initialize the eye position.
  404.     EyeR = 10
  405.     EyeTheta = PI * 0.2
  406.     EyePhi = PI * 0.1
  407.     
  408.     ' Initialize the projection transformation.
  409.     m3PProject Projector, m3Perspective, EyeR, EyePhi, EyeTheta, FocusX, FocusY, FocusZ, 0, 1, 0
  410.     
  411.     ' Create the data.
  412.     CreateData (ShowAxesCheck.value = vbChecked)
  413.  
  414.     ' Project and draw the data.
  415.     Me.Show
  416.     DrawData Pict
  417. End Sub
  418.  
  419.  
  420.  
  421. ' ************************************************
  422. ' Create the surface.
  423. ' ************************************************
  424. Sub CreateData(show_axes As Boolean)
  425. Const Xmin = -5     ' The area the grid should cover.
  426. Const Zmin = -5
  427. Const Xmax = -Xmin
  428. Const Zmax = -Zmin
  429. Const GapX = 0.5    ' Distance between curves parallel
  430. Const GapZ = 0.5    '   to the X and Z axes.
  431. Const Dx = 0.1      ' Distance between points along
  432. Const Dz = 0.1      '   the curves.
  433.  
  434. Dim refined As ObjPicture   ' The refined grid.
  435. Dim pline As ObjPolyline    ' A polyline in the grid.
  436. Dim axis As ObjPolyline
  437. Dim i As Integer
  438. Dim j As Integer
  439. Dim x As Single
  440. Dim y As Single
  441. Dim z As Single
  442. Dim x1 As Single
  443. Dim y1 As Single
  444. Dim z1 As Single
  445.  
  446.     MousePointer = vbHourglass
  447.     Refresh
  448.     
  449.     Set ThePicture = New ObjPicture
  450.     Set refined = New ObjPicture
  451.     ThePicture.objects.Add refined
  452.  
  453.     If show_axes Then
  454.         Set axis = New ObjPolyline
  455.         ThePicture.objects.Add axis
  456.         axis.AddSegment 0, 0, 0, 5.5, 0, 0
  457.         axis.AddSegment 0, 0, 0, 0, 3, 0
  458.         axis.AddSegment 0, 0, 0, 0, 0, 5.5
  459.     End If
  460.     
  461.     ' Create polylines parallel to the X axis.
  462.     For z = Zmin To Zmax Step GapZ
  463.         Set pline = New ObjPolyline
  464.         refined.objects.Add pline
  465.         
  466.         x1 = Xmin
  467.         y1 = SurfaceValue(Xmin, z)
  468.         z1 = z
  469.         
  470.         For x = Xmin + Dx To Xmax Step Dx
  471.             y = SurfaceValue(x, z)
  472.             pline.AddSegment x1, y1, z1, x, y, z
  473.             x1 = x
  474.             y1 = y
  475.             z1 = z
  476.         Next x
  477.     Next z
  478.     
  479.     ' Create polylines parallel to the Z axis.
  480.     For x = Xmin To Xmax Step GapX
  481.         Set pline = New ObjPolyline
  482.         refined.objects.Add pline
  483.         
  484.         x1 = x
  485.         y1 = SurfaceValue(x, Zmin)
  486.         z1 = Zmin
  487.         
  488.         For z = Zmin + Dz To Zmax Step Dz
  489.             y = SurfaceValue(x, z)
  490.             pline.AddSegment x1, y1, z1, x, y, z
  491.             x1 = x
  492.             y1 = y
  493.             z1 = z
  494.         Next z
  495.     Next x
  496. End Sub
  497.  
  498. Private Sub mnuFileExit_Click()
  499.     Unload Me
  500. End Sub
  501.  
  502.  
  503. Private Sub mnuFileLoad_Click()
  504. Dim fname As String
  505. Dim filenum As Integer
  506. Dim txt As String
  507. Dim Xmin As Single
  508. Dim Ymin As Single
  509. Dim Xmax As Single
  510. Dim Ymax As Single
  511.  
  512.     ' Allow the user to pick a file.
  513.     On Error Resume Next
  514.     LoadDialog.filename = "*.APF"
  515.     LoadDialog.ShowOpen
  516.     If Err.Number = cdlCancel Then
  517.         Unload LoadDialog
  518.         Exit Sub
  519.     ElseIf Err.Number <> 0 Then
  520.         Unload LoadDialog
  521.         Beep
  522.         MsgBox "Error selecting file.", , vbExclamation
  523.         Exit Sub
  524.     End If
  525.     On Error GoTo 0
  526.     
  527.     MousePointer = vbHourglass
  528.     DoEvents
  529.     
  530.     fname = LoadDialog.filename
  531.     LoadDialog.InitDir = Left$(fname, Len(fname) _
  532.         - Len(LoadDialog.FileTitle) - 1)
  533.  
  534.     ' Clear the picture.
  535.     Set ThePicture = Nothing
  536.     
  537.     ' Open the file.
  538.     filenum = FreeFile
  539.     Open fname For Input As #filenum
  540.     
  541.     ' Make sure it's an Object Picture File.
  542.     Input #filenum, txt
  543.     If txt <> "3D APF PICTURE" Then
  544.         Close filenum
  545.         Beep
  546.         MsgBox "Error reading file """ & fname & """.", , vbExclamation
  547.         Exit Sub
  548.     End If
  549.  
  550.     ' Read the picture.
  551.     Set ThePicture = New ObjPicture
  552.     ThePicture.FileInput filenum
  553.     
  554.     ' Close the file.
  555.     Close filenum
  556.  
  557.     ' Refresh the display.
  558.     DrawData Pict
  559.     
  560.     ' Deselect all the option buttons.
  561.     For ChoiceNum = 0 To 8
  562.         If Choice(ChoiceNum).value Then _
  563.             Choice(ChoiceNum).value = False
  564.     Next ChoiceNum
  565.  
  566.     MousePointer = vbDefault
  567. End Sub
  568.  
  569.  
  570.  
  571. Private Sub mnuFileSaveAs_Click()
  572. Dim fname As String
  573. Dim filenum As Integer
  574.  
  575.     ' Allow the user to pick a file.
  576.     On Error Resume Next
  577.     LoadDialog.filename = "*.APF"
  578.     LoadDialog.Flags = cdlOFNOverwritePrompt + cdlOFNHideReadOnly
  579.     LoadDialog.ShowSave
  580.     If Err.Number = cdlCancel Then
  581.         Unload LoadDialog
  582.         Exit Sub
  583.     ElseIf Err.Number <> 0 Then
  584.         Unload LoadDialog
  585.         Beep
  586.         MsgBox "Error selecting file.", , vbExclamation
  587.         Exit Sub
  588.     End If
  589.     On Error GoTo 0
  590.     
  591.     fname = LoadDialog.filename
  592.     LoadDialog.InitDir = Left$(fname, Len(fname) _
  593.         - Len(LoadDialog.FileTitle) - 1)
  594.     
  595.     ' Open the file.
  596.     filenum = FreeFile
  597.     Open fname For Output As #filenum
  598.     
  599.     ' Write the picture.
  600.     ThePicture.FileWrite filenum
  601.     
  602.     ' Close the file.
  603.     Close filenum
  604. End Sub
  605.  
  606.  
  607.  
  608. Private Sub PhiText_Change()
  609.     If ShowingParameters Then Exit Sub
  610.     EyePhi = CSng(PhiText.Text)
  611.     m3PProject Projector, m3Perspective, EyeR, EyePhi, EyeTheta, FocusX, FocusY, FocusZ, 0, 1, 0
  612.     DrawData Pict
  613. End Sub
  614.  
  615. Private Sub RText_Change()
  616.     If ShowingParameters Then Exit Sub
  617.     EyeR = CSng(RText.Text)
  618.     m3PProject Projector, m3Perspective, EyeR, EyePhi, EyeTheta, FocusX, FocusY, FocusZ, 0, 1, 0
  619.     DrawData Pict
  620. End Sub
  621.  
  622.  
  623. Private Sub ShowAxesCheck_Click()
  624.     CreateData (ShowAxesCheck.value = vbChecked)
  625.     DrawData Pict
  626.     Pict.SetFocus
  627. End Sub
  628.  
  629.  
  630. Private Sub ThetaText_Change()
  631.     If ShowingParameters Then Exit Sub
  632.     EyeTheta = CSng(ThetaText.Text)
  633.     m3PProject Projector, m3Perspective, EyeR, EyePhi, EyeTheta, FocusX, FocusY, FocusZ, 0, 1, 0
  634.     DrawData Pict
  635. End Sub
  636.  
  637.